#!/usr/bin/perl

#
#       Copyright (C) 2008-2012 Александр Девяткин, "Зелёная горка"
#
#       Разрешается повторное распространение и использование как в виде исходного
#       кода, так и в двоичной форме, с изменениями или без, при соблюдении следующих
#       условий:
#
#       * При повторном распространении исходного кода должно оставаться указанное
#         выше уведомление об авторском праве, этот список условий и последующий
#         отказ от гарантий.
#       * При повторном распространении двоичного кода должна сохраняться указанная
#         выше информация об авторском праве, этот список условий и последующий отказ
#         от гарантий в документации и/или в других материалах, поставляемых при
#         распространении.
#       * Ни название "Зелёная горка", ни имена ее сотрудников не могут быть
#         использованы в качестве поддержки или продвижения продуктов, основанных
#         на этом ПО без предварительного письменного разрешения.
#
#       ЭТА ПРОГРАММА ПРЕДОСТАВЛЕНА ВЛАДЕЛЬЦАМИ АВТОРСКИХ ПРАВ И/ИЛИ ДРУГИМИ СТОРОНАМИ
#	"КАК ОНА ЕСТЬ" БЕЗ КАКОГО-ЛИБО ВИДА ГАРАНТИЙ, ВЫРАЖЕННЫХ ЯВНО ИЛИ ПОДРАЗУМЕВАЕМЫХ,
#	ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ИМИ, ПОДРАЗУМЕВАЕМЫЕ ГАРАНТИИ КОММЕРЧЕСКОЙ ЦЕННОСТИ
#	И ПРИГОДНОСТИ ДЛЯ КОНКРЕТНОЙ ЦЕЛИ. НИ В КОЕМ СЛУЧАЕ, ЕСЛИ НЕ ТРЕБУЕТСЯ
#	СООТВЕТСТВУЮЩИМ ЗАКОНОМ, ИЛИ НЕ УСТАНОВЛЕНО В УСТНОЙ ФОРМЕ, НИ ОДИН ВЛАДЕЛЕЦ
#	АВТОРСКИХ ПРАВ И НИ ОДНО ДРУГОЕ ЛИЦО, КОТОРОЕ МОЖЕТ ИЗМЕНЯТЬ И/ИЛИ ПОВТОРНО
#	РАСПРОСТРАНЯТЬ ПРОГРАММУ, КАК БЫЛО СКАЗАНО ВЫШЕ, НЕ НЕСЁТ ОТВЕТСТВЕННОСТИ,
#	ВКЛЮЧАЯ ЛЮБЫЕ ОБЩИЕ, СЛУЧАЙНЫЕ, СПЕЦИАЛЬНЫЕ ИЛИ ПОСЛЕДОВАВШИЕ УБЫТКИ,
#	ВСЛЕДСТВИЕ ИСПОЛЬЗОВАНИЯ ИЛИ НЕВОЗМОЖНОСТИ ИСПОЛЬЗОВАНИЯ ПРОГРАММЫ (ВКЛЮЧАЯ,
#	НО НЕ ОГРАНИЧИВАЯСЬ ПОТЕРЕЙ ДАННЫХ, ИЛИ ДАННЫМИ, СТАВШИМИ НЕПРАВИЛЬНЫМИ, ИЛИ
#	ПОТЕРЯМИ ПРИНЕСЕННЫМИ ИЗ-ЗА ВАС ИЛИ ТРЕТЬИХ ЛИЦ, ИЛИ ОТКАЗОМ ПРОГРАММЫ РАБОТАТЬ
#	СОВМЕСТНО С ДРУГИМИ ПРОГРАММАМИ), ДАЖЕ ЕСЛИ ТАКОЙ ВЛАДЕЛЕЦ ИЛИ ДРУГОЕ ЛИЦО БЫЛИ
#	ИЗВЕЩЕНЫ О ВОЗМОЖНОСТИ ТАКИХ УБЫТКОВ.
#

#       Copyright (C) 2008-2012 Aleksandr Deviatkin, "Green Hill"
#
#       Redistribution and use in source and binary forms, with or without
#       modification, are permitted provided that the following conditions are
#       met:
#       
#       * Redistributions of source code must retain the above copyright
#         notice, this list of conditions and the following disclaimer.
#       * Redistributions in binary form must reproduce the above
#         copyright notice, this list of conditions and the following disclaimer
#         in the documentation and/or other materials provided with the
#         distribution.
#       * Neither the name of the Green Hill nor the names of its
#         contributors may be used to endorse or promote products derived from
#         this software without specific prior written permission.
#       
#       THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
#       "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
#       LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
#       A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
#       OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#       SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
#       LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
#       DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
#       THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
#       (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
#       OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#


$|=1;
use DBI;
#use Time::Local;
use strict;

#
# Построение графиков на луче
# 2012-01-02 alid
#

my (@args, %opts);
foreach(@ARGV){
	if(/^\-(\S)(\S*)/) { $opts{$1} = $2; } else {  push @args, $_; }
}
my ($database,$mgid) = (@args);
die "Usage: $0 database counter_id group_id [start date] [end date]"		unless($database);
my $verb = exists $opts{v};
my $pgport = 5432;

my $dpath = $ENV{MY}."data/$database/rrd";
my $gpath = $ENV{MY}."data/$database/graph";
my $balcmd = $ENV{MY}."counter/balance";
my $canbalance = 0;


my $dbh = DBI->connect("dbi:Pg:dbname=$database;port=$pgport","","", { RaiseError => 1});
# Список счетчиков луча
my @Glist;
my $cnt = 0;
my $sth = $dbh->prepare("select id from counters where mgroup=? and active=1");
$sth->execute($mgid);
while(my $r = $sth->fetchrow_arrayref) {
	push @Glist, $r->[0];
	$cnt++;
}
$sth->finish;

# Каталоги для базы и графиков этого луча
unless(-d "$dpath/$mgid") {
	mkdir "$dpath/$mgid"	or die "Can't create database directory: $dpath/$mgid - $!";
}
unless(-d "$gpath/$mgid") {
	mkdir "$gpath/$mgid"	or die "Can't create graph directory: $gpath/$mgid - $!";
}

# Балансный счетчик этого луча
$sth = $dbh->prepare("select bid from mgroup where id=?");
$sth->execute($mgid);
my ($cid) = $sth->fetchrow_array;
$sth->finish;
unless($cid) {
	print "Can't found Balance counter id for group $mgid\n"	if($verb);
} else {
	# Баланс на луче
	unless(-e "$dpath/$mgid/balance.rrd") {	# база баланса
		my $res = system("rrdtool","create","$dpath/$mgid/balance.rrd","--start","1200000000","--step","300","DS:delta:GAUGE:600:U:U","RRA:AVERAGE:0.1:1:600","RRA:AVERAGE:0.1:6:300","RRA:AVERAGE:0.1:24:300","RRA:AVERAGE:0.1:72:300","RRA:AVERAGE:0.1:288:300");
		die "Can't create balance database: $dpath/$mgid/balance.rrd - $!"	if $res;
	}
	my $bal = `$balcmd $database $cid $mgid`;
	my ($tm,$val,undef) = split(/\s/,$bal);
	if($tm && defined $val) {
		my $tmlast;
		eval{$tmlast = system("rrdtool","last","$dpath/$mgid/balance.rrd"); };
		chomp $tmlast; $tmlast ||= 0;
		if($tm > $tmlast) {
		eval{my $res = system("rrdtool","update","$dpath/$mgid/balance.rrd","$tm:$val"); };
	#	warn "Can't update balance database: $!"	if $res;
		}
	}


	# Графики баланс
	system("rrdtool graph $gpath/$mgid/balance-day.png --imgformat PNG -z "
		."--start -24h --end now "
		."--title \"Balance today\" "
		."DEF:delta=$dpath/$mgid/balance.rrd:delta:AVERAGE "
		."LINE:delta#FF0000:Delta"
	." >/dev/null");
	system("rrdtool graph $gpath/$mgid/balance-yesterday.png --imgformat PNG -z "
		."--start -48h --end -24h "
		."--title \"Balance yesterday\" "
		."DEF:delta=$dpath/$mgid/balance.rrd:delta:AVERAGE "
		."LINE:delta#FF0000:Delta"
	." >/dev/null");
	system("rrdtool graph $gpath/$mgid/balance-week.png --imgformat PNG -z "
		."--start -7d --end now "
		."--title \"Balance last week\" "
		."DEF:delta=$dpath/$mgid/balance.rrd:delta:AVERAGE "
		."LINE:delta#FF0000:Delta"
	." >/dev/null");
	system("rrdtool graph $gpath/$mgid/balance-month.png --imgformat PNG -z "
		."--start -30d --end now "
		."--title \"Balance last month\" "
		."DEF:delta=$dpath/$mgid/balance.rrd:delta:AVERAGE "
		."LINE:delta#FF0000:Delta"
	." >/dev/null");
	system("rrdtool graph $gpath/$mgid/balance-3month.png --imgformat PNG -z "
		."--start -91d --end now "
		."--title \"Balance last three month\" "
		."DEF:delta=$dpath/$mgid/balance.rrd:delta:AVERAGE "
		."LINE:delta#FF0000:Delta"
	." >/dev/null");
	system("rrdtool graph $gpath/$mgid/balance-year.png --imgformat PNG -z "
		."--start -365d --end now "
		."--title \"Balance last year\" "
		."DEF:delta=$dpath/$mgid/balance.rrd:delta:AVERAGE "
		."LINE:delta#FF0000:Delta"
	." >/dev/null");
}	# balance

# Графики потребления счетчиков луча
$sth = $dbh->prepare("select date,ise from ONLY monitor where counter=? order by date desc limit 1");
foreach my $id (@Glist) {
	unless(-e "$dpath/$mgid/$id.rrd") {	# база этого счетчика
		my $res = system("rrdtool","create","$dpath/$mgid/$id.rrd","--start","1200000000","--step","300","DS:ise:GAUGE:600:U:U","RRA:AVERAGE:0.1:1:600","RRA:AVERAGE:0.1:6:300","RRA:AVERAGE:0.1:24:300","RRA:AVERAGE:0.1:72:300","RRA:AVERAGE:0.1:288:300");
		die "Can't create counter database: $dpath/$mgid/$id.rrd - $!"	if $res;
	}
	$sth->execute($id);
	my ($tm,$val) = $sth->fetchrow_array;
	$sth->finish;
	if($tm && defined $val) {
		$val *= 1000;	# Ватты
		my $tmlast;
		eval{ $tmlast = system("rrdtool","last","$dpath/$mgid/$id.rrd"); };
		chomp $tmlast; $tmlast ||= 0;
		if($tm > $tmlast) {
		eval{ my $res = system("rrdtool","update","$dpath/$mgid/$id.rrd","$tm:$val"); };
#		warn "Can't update counter database: $!"	if $res;
		}
	}

	system("rrdtool graph $gpath/$mgid/$id-day.png --imgformat PNG -z "
		."--start -24h --end now "
		."--title \"Power today\" "
		."DEF:ise=$dpath/$mgid/$id.rrd:ise:AVERAGE "
		."LINE:ise#0000FF:Power"
	." >/dev/null");
	system("rrdtool graph $gpath/$mgid/$id-yesterday.png --imgformat PNG -z "
		."--start -48h --end -24h "
		."--title \"Power yesterday\" "
		."DEF:ise=$dpath/$mgid/$id.rrd:ise:AVERAGE "
		."LINE:ise#0000FF:Power"
	." >/dev/null");
	system("rrdtool graph $gpath/$mgid/$id-week.png --imgformat PNG -z "
		."--start -7d --end now "
		."--title \"Power last week\" "
		."DEF:ise=$dpath/$mgid/$id.rrd:ise:AVERAGE "
		."LINE:ise#0000FF:Power"
	." >/dev/null");
	system("rrdtool graph $gpath/$mgid/$id-month.png --imgformat PNG -z "
		."--start -30d --end now "
		."--title \"Power last month\" "
		."DEF:ise=$dpath/$mgid/$id.rrd:ise:AVERAGE "
		."LINE:ise#0000FF:Power"
	." >/dev/null");
	system("rrdtool graph $gpath/$mgid/$id-3month.png --imgformat PNG -z "
		."--start -91d --end now "
		."--title \"Power last three month\" "
		."DEF:ise=$dpath/$mgid/$id.rrd:ise:AVERAGE "
		."LINE:ise#0000FF:Power"
	." >/dev/null");
	system("rrdtool graph $gpath/$mgid/$id-year.png --imgformat PNG -z "
		."--start -365d --end now "
		."--title \"Power last year\" "
		."DEF:ise=$dpath/$mgid/$id.rrd:ise:AVERAGE "
		."LINE:ise#0000FF:Power"
	." >/dev/null");

}

$dbh->disconnect;


